﻿define(function (require, exports, module) {
    var PDFTextObject = require('../../PDFData/Text/Reader_TextObject.js');
    var PDFTextPage = require('../../PDFData/Text/Reader_TextPage.js');
    var RectUtils = WebPDF.RectUtils;
    var CommonTools = WebPDF.Common;
    var CMap = WebPDF.CMap;

    /**
     * @name WebPDF.TextSelect
     * @ignore
     * @namespace 这是一个命名空间包含所有有关文本操作类。
     */
    WebPDF.TextSelect = {};

    var TextSelectRange = function (startIndex, endIndex) {
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    };
    WebPDF.TextSelect.TextSelectRange = TextSelectRange;

    WebPDF.TEXT_RETURN_LINEFEED = "\r\n";

    /**
     * @ignore
     * @description 文本页面的选择文本信息类
     * @class 文本页面的选择文本信息类
     * @constructor
     */
    WebPDF.TextSelect.CReader_TextPageSelect = function () {
        var _textPage = null,  //pdf文本页面对象
            /**
             * 文本选择范围列表
             * @type {Array.<TextSelectRange>}
             * @private
             */
            _selectedRangeList = [],
            /**
             * 需要绘制的文本选择范围列表
             * @type {Array.<TextSelectRange>}
             * @private
             */
            _needDrawSelectedRangeList = [],
            /**
             * 需要清除的文本选择范围列表
             * @type {Array.<TextSelectRange>}
             * @private
             */
            _needClearSelectedRangeList = [];

        /**
         * @description 设置PDF文本页面对象
         * @param {WebPDF.PDFData.Text.PDFTextPage} textPage PDF文本页面对象
         * @return {WebPDF.PDFData.Text.PDFTextPage} 之前的PDF文本页面对象;
         */
        this.setTextPage = function (textPage) {
            var oldTextPage = _textPage;
            _textPage = textPage;
            return oldTextPage;
        };
        
        /**
         * @description 添加选择区域，依据范围选择区域
         * @param {WebPDF.PDFRect} rcBound 范围选择区域
         */
        this.addSelectedRect = function (rcBound) {
            if (!_textPage)
                return;
            RectUtils.normalize(rcBound);
            var boundArray = [];
            _needDrawSelectedRangeList = [];
            _needClearSelectedRangeList = [];
            if (!_textPage.getBoundPageInfo(rcBound, boundArray)) {
                _needClearSelectedRangeList.length = 0;
                _needClearSelectedRangeList = CommonTools.clone(_selectedRangeList);
                _selectedRangeList.length = 0;
                _needDrawSelectedRangeList.length = 0;
                return;
            }
            var count = _selectedRangeList.length;
            var size;
            if (count == 0) {
                size = boundArray.length;
                for (var i = 0; i < size; i++) {
                    _selectedRangeList.push(new TextSelectRange(boundArray[i].startIndex, boundArray[i].endIndex));
                }
                _needDrawSelectedRangeList = [];
                _needDrawSelectedRangeList = CommonTools.clone(_selectedRangeList);
                return;
            }
            var boundMap1 = new CMap();
            var boundMap2 = new CMap();
            var map = new CMap();
            size = boundArray.length;
            for (var i = 0; i < size; i++) {
                var lineIndex = _textPage.getLineIndexByIndex(boundArray[i].startIndex);
                boundMap1.put(lineIndex, i);
                boundMap2.put(i, lineIndex);
            }

            for (var j = 0; j < count; j++) {
                var lineIndex = _textPage.getLineIndexByIndex(_selectedRangeList[j].startIndex);
                map.put(lineIndex, j);
                var value = boundMap1.get(lineIndex);
                if (value != null) {
                    _addSelectedRect(_selectedRangeList[j], boundArray[value].startIndex, boundArray[value].endIndex);
                }
                else {
                    _needClearSelectedRangeList.push(CommonTools.clone(_selectedRangeList[j]));
                }
            }

            for (var k = 0; k < size; k++) {
                var lineIndex = boundMap2.get(k);
                if (lineIndex == null)
                    return;
                var value = map.get(lineIndex);
                if (value == null) {
                    _needDrawSelectedRangeList.push(new TextSelectRange(boundArray[k].startIndex, boundArray[k].endIndex));
                }
            }

            _selectedRangeList = [];
            for (var m = 0; m < size; m++) {
                _selectedRangeList.push(new TextSelectRange(boundArray[m].startIndex, boundArray[m].endIndex));
            }
        };

        /**
         * @description 添加选择区域，依据字符索引
         * @param {Number} startIndex 开始字符索引
         * @param {Number} endIndex 结束字符索引
         */
        this.addSelectedRectByIndex = function (startIndex, endIndex) {
            if (!_textPage)
                return;
            if (startIndex > endIndex || startIndex < 0 || endIndex > _textPage.getSize()) {
                this.clearSelectRect();
                return;
            }
            if (_selectedRangeList.length == 0) {
                _needDrawSelectedRangeList = [];
                _needClearSelectedRangeList = [];
                _selectedRangeList.push(new TextSelectRange(startIndex,endIndex));
                _needDrawSelectedRangeList = CommonTools.clone(_selectedRangeList);
            }
            else {
                var sl_info = _selectedRangeList[0];
                _needDrawSelectedRangeList = [];
                _needClearSelectedRangeList = [];
                _addSelectedRect(sl_info, startIndex, endIndex);
                _selectedRangeList = [];
                _selectedRangeList.push(new TextSelectRange(startIndex,endIndex));
            }
        };

        function _addSelectedRect(sl_info, startIndex, endIndex) {
            if (_textPage == null || startIndex > endIndex)
                return;
            var new_info = new TextSelectRange(-1, -1);
            //needClear
            if (startIndex > sl_info.startIndex) {
                if (startIndex <= sl_info.endIndex) {
                    new_info.startIndex = sl_info.startIndex;
                    new_info.endIndex = startIndex - 1;
                    _needClearSelectedRangeList.push(new_info);
                }
                else {
                    _needClearSelectedRangeList.push(sl_info);
                }
            }
            if (endIndex < sl_info.endIndex) {
                if (endIndex >= sl_info.startIndex) {
                    new_info.startIndex = endIndex + 1;
                    new_info.endIndex = sl_info.endIndex;
                    _needClearSelectedRangeList.push(new_info);
                }
                else {
                    _needClearSelectedRangeList.push(sl_info);
                }
            }
            //needDraw
            if (sl_info.startIndex > startIndex) {
                if (sl_info.startIndex <= endIndex) {
                    new_info.startIndex = startIndex;
                    new_info.endIndex = sl_info.startIndex - 1;
                    _needDrawSelectedRangeList.push(new_info);
                }
                else {
                    new_info.startIndex = startIndex;
                    new_info.endIndex = endIndex;
                    _needDrawSelectedRangeList.push(new_info);
                }
            }
            if (sl_info.endIndex < endIndex) {
                if (sl_info.endIndex >= startIndex) {
                    new_info.startIndex = sl_info.endIndex + 1;
                    new_info.endIndex = endIndex;
                    _needDrawSelectedRangeList.push(new_info);
                }
                else {
                    new_info.startIndex = startIndex;
                    new_info.endIndex = endIndex;
                    _needDrawSelectedRangeList.push(new_info);
                }
            }
        }

        /**
         * @description 清楚选择区域
         */
        this.clearSelectRect = function () {
            if (!_textPage) {
                return;
            }
            _needDrawSelectedRangeList.length = 0;
            _needClearSelectedRangeList.length = 0;
            _needClearSelectedRangeList = CommonTools.clone(_selectedRangeList);
            _selectedRangeList.length = 0;
        };

        /**
         * @description 选择文本页面中全部文本
         */
        this.selectAll = function () {
            if (!_textPage) {
                return;
            }
            _needDrawSelectedRangeList.length = 0;
            _needClearSelectedRangeList.length = 0;
            _needClearSelectedRangeList = CommonTools.clone(_selectedRangeList);
            var newInfo = new TextSelectRange(0,_textPage.getSize() - 1);
            _selectedRangeList.length = 0;
            _selectedRangeList.push(newInfo);
            _needDrawSelectedRangeList.push(newInfo);
        };
        /**
         * @description 是否存在已选择文本
         * @return {Boolean} 存在已选择文本返回true,否则false;
         */
        this.isSelected = function () {
            return _selectedRangeList.length > 0;
        };
        /**
         * @description 获取已选择文本的区域数组
         * @param {Array.<{WebPDF.PDFRect}>} rectArray 区域数组
         * @return {Number} 返回区域数组长度;
         */
        this.getSelectPDFRect = function (rectArray) {
            rectArray.length = 0;
            var size = _selectedRangeList.length;
            for (var i = 0; i < size; i++) {
                var startIndex = _selectedRangeList[i].startIndex;
                var count = _selectedRangeList[i].endIndex - _selectedRangeList[i].startIndex + 1;
                if (count <= 0) {
                    continue;
                }
                var tmpRectArr = _textPage.getPDFRect(startIndex, count);
                for (var j = 0; j < tmpRectArr.length; j++) {
                    rectArray.push(tmpRectArr[j]);
                }
            }
            return rectArray.length;
        };

        this.getNeedDrawPDFRect = function (rectArray) {
            rectArray.length = 0;
            var size = _needDrawSelectedRangeList.length;
            for (var i = 0; i < size; i++) {
                var startIndex = _needDrawSelectedRangeList[i].startIndex;
                var count = _needDrawSelectedRangeList[i].endIndex - _needDrawSelectedRangeList[i].startIndex + 1;
                if (count <= 0) {
                    continue;
                }
                var tmpRectArr = _textPage.getPDFRect(startIndex, count);
                for (var j = 0; j < tmpRectArr.length; j++) {
                    rectArray.push(tmpRectArr[j]);
                }
            }
            return rectArray.length;
        };

        this.getNeedClearPDFRect = function (rectArray) {
            rectArray.length = 0;
            var size = _needClearSelectedRangeList.length;
            for (var i = 0; i < size; i++) {
                var startIndex = _needClearSelectedRangeList[i].startIndex;
                var count = _needClearSelectedRangeList[i].endIndex - _needClearSelectedRangeList[i].startIndex + 1;
                if (count <= 0) {
                    continue;
                }
                rectArray = _textPage.getPDFRect(startIndex, count);
            }
            return rectArray.length;
        };

        /**
         * @description 获取已选择文本字符串
         * @return {String} 返回已选择文本字符串;
         */
        this.getSelectedText = function () {
            var csText = "";
            var size = _selectedRangeList.length;
            for (var i = 0; i < size; i++) {
                var startIndex = _selectedRangeList[i].startIndex;
                var count = _selectedRangeList[i].endIndex - _selectedRangeList[i].startIndex + 1;
                if (count <= 0) {
                    continue;
                }
                csText += _textPage.getPageText(startIndex, count);
                if (i < size - 1) {
                    csText += WebPDF.TEXT_RETURN_LINEFEED;
                }
            }
            return csText;
        };
        /**
         * @description 获取最先的插入符信息
         * @param {WebPDF.PDFData.Text.CaretInfo} caretInfo 返回插入符信息
         */
        this.getFirstCaretInfo = function (caretInfo) {
            caretInfo.index = -1;
            if (_selectedRangeList.length != 0) {
                _textPage.getCaretByIndex(_selectedRangeList[0].startIndex, caretInfo, true);
            }
        };
        
        
        this.getSelectPDFRectAndMatrix = function (rect_array,matrixArray,writingModeArray) {
            rect_array.length = 0;
			matrixArray.length = 0;
            var size = _selectedRangeList.length;
            for (var i = 0; i < size; i++) {
                var start_index = _selectedRangeList[i].startIndex;
                var count = _selectedRangeList[i].endIndex - _selectedRangeList[i].startIndex + 1;
                if (count <= 0) {
                    continue;
                }
                var tmpRectArr = _textPage.getPDFRect(start_index, count,matrixArray,writingModeArray);
                for (var j = 0; j < tmpRectArr.length; j++) {
                    rect_array.push(tmpRectArr[j]);
                }
            }
            return rect_array.length;
        }
    };

    return WebPDF.TextSelect.CReader_TextPageSelect;
});